#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <getopt.h>
#include "globle.h"


#define LOG_TAG  "parse_para.c  :"

extern char* optarg;
extern int optopt, opterr;
// -b 4 -l 1024 -c 4 -s 1024 -i 0 -r 0 -m 3 -d 1
static void show_usage()
{
    LOG("usage: ./you_prog [-r c2h_channel_number] ... \r\n");
    //////////////////////////////////////////////
    LOG("-b [num of user side ring buffer blocks]\r\n");
    LOG("-l [size of user side ring buffer blocks,must be multiple of fpga_side_ring_buffer_block_size,1 for 1KB]\r\n");
    LOG("-c [num of fpga side ring buffer blocks,max ->256]\r\n");
    LOG("-s [size of fpga side ring buffer block,1 for 1KB]\r\n");
    //////////////////////////////////////////////
    LOG("-m [monitor period,1 for 1s\r\n");
    LOG("-n [num of user data channels\r\n");
    LOG("-d [direction 1:read from xmda,2:write to xdma,3:read/write]\r\n");
    LOG("-t [deliver_data 1:deliver,0:do not deliver_data]\r\n");
    LOG("-h [show usage]\r\n");
}
// b:l:c:s:i:r:w:d:m:t:h
int parse_arg(xdma_usr_dev *xdma_dev, int argc, char * const argv[], const char *optstring) // -s -p -f
{
    int opt = 0, ret_val = 0;
    char *stop_point = NULL, *tmp_buff = NULL;
#define NAME_LEN 100

    LOGD("parse para start!\r\n");
    opterr = 0;

    if (!xdma_dev)
    {
        LOGE(LOG_TAG"%s null point,exit!\r\n", __func__);
        return -1;
    }

    while ((opt = getopt(argc, argv, optstring)) != -1)
    {
        switch (opt)
        {
            case 'b':
                xdma_dev->user_side_ring_buffer_block_num = strtol(optarg, &stop_point, 0);
                LOGD("user_side_ring_buffer_block_num %d\r\n", xdma_dev->user_side_ring_buffer_block_num);
                break;
            case 'l':
                xdma_dev->user_side_ring_buffer_block_size = strtol(optarg, &stop_point, 0) * K_B;
                LOGD("user_side_ring_buffer_block_size %uKB\r\n", (uint32_t)(xdma_dev->user_side_ring_buffer_block_size / K_B));
                break;
            case 'c':
                xdma_dev->fpga_side_ring_buffer_block_num = strtol(optarg, &stop_point, 0);
                LOGD("fpga_side_ring_buffer_block_num %u\r\n", xdma_dev->fpga_side_ring_buffer_block_num);
                break;
            case 's':
                xdma_dev->fpga_side_ring_buffer_block_size = strtol(optarg, &stop_point, 0) * K_B;
                LOGD("fpga_side_ring_buffer_block_size %uKB\r\n", (uint32_t)(xdma_dev->fpga_side_ring_buffer_block_size / K_B));
                break;
            case 'd':
                xdma_dev->direction = atoi(optarg);
                LOG("xdma_dev->direction :%d,%s\r\n", xdma_dev->direction, xdma_dev->direction == C2H_READ_DATA ? "read" : (xdma_dev->direction == H2C_WRITE_DATA ? "write" : "read/write"));
                break;
            case 'm':
                xdma_dev->monitor_period = atoi(optarg);
                LOG("xdma_dev->monitor_period :%ds\r\n", xdma_dev->monitor_period);
                break;
            case 'n':
                xdma_dev->num_of_user_data_channel = atoi(optarg);
                LOG("xdma_dev->num_of_user_data_channel :%ds\r\n", xdma_dev->num_of_user_data_channel);
                break;
            case 't':
                xdma_dev->deliver_data = atoi(optarg);
                LOG("xdma_dev->deliver_data :%d\r\n", xdma_dev->deliver_data);
                break;
            case 'h':
                show_usage();
                exit(0);
                break;
            case '?':
                LOG("illegal argument \"-%c\"\n", optopt);
                ret_val = -1;
                show_usage();
                break;
            case ':':
                LOG("\"-%c\" needs a parameter\n", optopt);
                ret_val = -1;
                show_usage();
                break;
            default:
                show_usage();
                ret_val = -1;
                break;
        }
    }

    if (xdma_dev->user_side_ring_buffer_block_num < xdma_dev->num_of_user_data_channel * 2 || xdma_dev->user_side_ring_buffer_block_num % xdma_dev->num_of_user_data_channel)
    {
        LOG("user_side_ring_buffer_block_num should >= %d,and must be divided by %d,exit\r\n", xdma_dev->num_of_user_data_channel * 2, xdma_dev->num_of_user_data_channel);
        return -1;
    }

    if (xdma_dev->fpga_side_ring_buffer_block_num < xdma_dev->num_of_user_data_channel * 2 || xdma_dev->fpga_side_ring_buffer_block_num % xdma_dev->num_of_user_data_channel)
    {
        LOG("fpga_side_ring_buffer_block_num should >= %d,and must be divided by %d,exit\r\n", xdma_dev->num_of_user_data_channel * 2, xdma_dev->num_of_user_data_channel);
        return -1;
    }
    LOGD("parse para end!\r\n");
#undef NAME_LEN
    return ret_val;
}
